# _*_ coding:UTF-8 _*_
__author__ = 'shede333'

import os
import hashlib
import re
import pickle
import sys
import shelve


g_config_file_name = ".config"  # 配置文件的文件名,放在当前目录(脚本文件)下


def test(test_str=""):
    print "This is Module, work fine!, in: ", os.path.split(sys.argv[0])[1]
    print __file__
    if len(test_str) > 0:
        print test_str


def please_user_input(prompt="please input:", is_force=False, func_confirm=None):
    user_input = raw_input(prompt)
    if is_force and ((user_input is None) or (len(user_input) <= 0)):
        user_input = please_user_input(prompt=prompt, is_force=is_force)
    elif func_confirm is not None:
        try:
            is_confirm = func_confirm(user_input)
        except Exception, e:
            print "参数func_confirm设置错误，它是带有一个参数的函数"
            is_confirm = True  # func_confirm have problem
        if not is_confirm:
            user_input = please_user_input(prompt=prompt, is_force=is_force, func_confirm=func_confirm)
    return user_input


def user_input_path(prompt="please input path:", is_dir=False):
    user_input = raw_input(prompt)
    user_input = os.path.expanduser(user_input)
    if is_dir:
        if os.path.isdir(user_input):
            return user_input
        else:
            print "path is not directory:", user_input
            return user_input_path(prompt, is_dir=is_dir)
    else:
        if os.path.exists(user_input):
            return user_input
        else:
            print "path is not exist:", user_input
        return user_input_path(prompt, is_dir=is_dir)


def user_input_bool(prompt="please input [yes] or [no]:"):
    user_input = raw_input(prompt)
    if user_input.startswith("y"):
        return True
    elif user_input.startswith("n"):
        return False
    else:
        return user_input_bool("input error, input [yes] or [no]:")


def cal_file_md5(file_path):
    if not os.path.isfile(file_path):
        return
    tmp_file = open(file_path, "rb")
    m1 = hashlib.md5(tmp_file.read()).hexdigest()
    tmp_file.close()
    return m1


def file_list_in_dir(dir_path, is_recursion=True, is_contain_hidden_file=False):
    if not os.path.isdir(dir_path):
        return []
    files = []
    tmp_file_list = os.listdir(dir_path)
    for file_name in tmp_file_list:
        if (not is_contain_hidden_file) and file_name.startswith("."):
                continue
        tmp_path = os.path.join(dir_path, file_name)
        if os.path.isfile(tmp_path):
            files.append((file_name, tmp_path))
        elif is_recursion and os.path.isdir(tmp_path):
            tmp_arr = file_list_in_dir(tmp_path, is_recursion=is_recursion,  is_contain_hidden_file=is_contain_hidden_file)
            files.extend(tmp_arr)

    return files


def ext_name_form(file_name):
    if not isinstance(file_name, str):
        return ""
    result_index = file_name.rfind(".")
    if result_index == -1:
        return ""
    else:
        return file_name[result_index+1:]


def file_list_recursion_dir(dir_path, ext_names=None, exclude_dirs=[]):
    if not os.path.isdir(dir_path):
        return []
    _file_list = []
    _ignored_files = ['.DS_Store']
    _ext_names = []
    if isinstance(ext_names, list) and len(ext_names) > 0:
        _ext_names.extend(ext_names)
    else:
        _ext_names = None
    for root, subDirs, files in os.walk(dir_path):
        is_excluded = False
        for tmp_dir_path in exclude_dirs:
            if re.search(tmp_dir_path, root) is not None:
                is_excluded = True
                break
        if is_excluded:
            continue

        for file_name in files:
            if file_name not in _ignored_files:
                if _ext_names is not None and len(_ext_names) > 0 and ext_name_form(file_name) not in _ext_names:
                        continue
                _file_list.append((file_name, os.path.join(root, file_name)))

    return _file_list


def list_convert_to_dic(origin_list, dic_default_value=1):
    tmp_dic = {}
    for tmp_element in origin_list:
        tmp_dic[tmp_element] = dic_default_value
    return tmp_dic


def get_current_dir():
    return (os.path.split(os.path.abspath(sys.argv[0])))[0]


def load_config(config_path=None):
    params = {}
    if config_path is None:
        config_path = os.path.join(get_current_dir(), g_config_file_name)
    config_params = shelve.open(config_path)
    try:
        for tmp_key in config_params.keys():
            params[tmp_key] = config_params[tmp_key]
    except Exception, e:
        pass
    finally:
        config_params.close()
    return params


def save_config(params, config_path=None):
    if config_path is None:
        config_path = os.path.join(get_current_dir(), g_config_file_name)
    config_params = shelve.open(config_path)
    try:
        for tmp_key in params:
            config_params[tmp_key] = params[tmp_key]
    except Exception, e:
        pass
    finally:
        config_params.close()


def print_list(tmp_list, prefix_str=""):
    for element in tmp_list:
        print prefix_str, element


def print_dic(tmp_dic, prefix_str=""):
    for tmp_key in tmp_dic:
        print prefix_str, tmp_key, " : ", tmp_dic[tmp_key]


def get_value_from_config(key_name=None, prompt=None, is_create_file_if_not_exist=True,  func_confirm=None):
    final_value = None
    config_file_path = os.path.join(get_current_dir(), g_config_file_name)
    config_dic = load_config(config_file_path)
    if key_name is None:
        # 使用默认值，默认值为当前执行的主脚本路径的md5值
        tmp_value = os.path.abspath(sys.argv[0])
        key_name = hashlib.md5(tmp_value).hexdigest()
    if key_name in config_dic:
        tmp_value = config_dic[key_name]
        print "是否使用已存储的值： %s : %s " % (key_name, tmp_value)
        if user_input_bool():  # 询问用户是否使用这个值
            final_value = tmp_value

    if final_value is None:
        if prompt is None:
            user_input_value = please_user_input(is_force=True, func_confirm=func_confirm)
        else:
            user_input_value = please_user_input(prompt=prompt, is_force=True, func_confirm=func_confirm)

        if user_input_value is not None:
            save_config(config_file_path, {key_name: user_input_value})
            final_value = user_input_value

    return final_value


def main():
    sys.exit()
    config_path = os.path.join(get_current_dir(), g_config_file_name)
    print config_path
    print "config1:", load_config()
    save_config(params={"k3":"vsdhk", "hello":"world"})
    print "config2:", load_config(config_path)
    sys.exit()
    dir_path = "/Volumes/Mac/iphone-pub"
    print "file_list_in_dir: ", len(file_list_in_dir(dir_path, is_recursion=True))
    print "file_list_recursion_dir: ", len(file_list_recursion_dir(dir_path))


if __name__ == '__main__':
    main()

